using System;
using System.Collections.Generic;

//
// * Copyright (c) 2002-2010 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.graphdb
{

///
/// <summary> * Defines a common API for handling properties on both <seealso cref="Node nodes"/> and
/// * <seealso cref="Relationship relationships"/>.
/// * <p>
/// * Properties are key-value pairs. The keys are always strings. Valid property
/// * value types are all the Java primitives (<code>int</code>, <code>byte</code>,
/// * <code>float</code>, etc), <code>java.lang.String</code>s and arrays of
/// * primitives and Strings.
/// * <p>
/// * <b>Please note</b> that Neo4j does NOT accept arbitrary objects as property
/// * values. <seealso cref="setProperty(String, Object) setProperty()"/> takes a
/// * <code>java.lang.Object</code> only to avoid an explosion of overloaded
/// * <code>setProperty()</code> methods. </summary>
/// 
	public interface PropertyContainer
	{
///    
///     <summary> * Returns <code>true</code> if this property container has a property
///     * accessible through the given key, <code>false</code> otherwise. If key is
///     * <code>null</code>, this method returns <code>false</code>.
///     *  </summary>
///     * <param name="key"> the property key </param>
///     * <returns> <code>true</code> if this property container has a property
///     *         accessible through the given key, <code>false</code> otherwise </returns>
///     
		bool HasProperty(string key);

///    
///     <summary> * Returns the property value associated with the given key. The value is of
///     * one of the valid property types, i.e. a Java primitive, a {@link String
///     * String} or an array of any of the valid types.
///     * <p>
///     * If there's no property associated with <code>key</code> an unchecked
///     * exception is raised. The idiomatic way to avoid an exception for an
///     * unknown key and instead get <code>null</code> back is to use a default
///     * value: {@link #getProperty(String, Object) Object valueOrNull =
///     * nodeOrRel.getProperty( key, null )}
///     *  </summary>
///     * <param name="key"> the property key </param>
///     * <returns> the property value associated with the given key </returns>
///     * <exception cref="NotFoundException"> if there's no property associated with
///     *             <code>key</code> </exception>
///     
		object GetProperty(string key);

///    
///     <summary> * Returns the property value associated with the given key, or a default
///     * value. The value is of one of the valid property types, i.e. a Java
///     * primitive, a <seealso cref="String String"/> or an array of any of the valid types.
///     *  </summary>
///     * <param name="key"> the property key </param>
///     * <param name="defaultValue"> the default value that will be returned if no
///     *            property value was associated with the given key </param>
///     * <returns> the property value associated with the given key </returns>
///     
		object GetProperty(string key, object defaultValue);

///    
///     <summary> * Sets the property value for the given key to <code>value</code>. The
///     * property value must be one of the valid property types, i.e:
///     * <ul>
///     * <li><code>boolean</code> or <code>boolean[]</code></li>
///     * <li><code>byte</code> or <code>byte[]</code></li>
///     * <li><code>short</code> or <code>short[]</code></li>
///     * <li><code>int</code> or <code>int[]</code></li>
///     * <li><code>long</code> or <code>long[]</code></li>
///     * <li><code>float</code> or <code>float[]</code></li>
///     * <li><code>double</code> or <code>double[]</code></li>
///     * <li><code>char</code> or <code>char[]</code></li>
///     * <li><code>java.lang.String</code> or <code>String[]</code></li>
///     * </ul>
///     * <p>
///     * This means that <code>null</code> is not an accepted property value.
///     *  </summary>
///     * <param name="key"> the key with which the new property value will be associated </param>
///     * <param name="value"> the new property value, of one of the valid property types </param>
///     * <exception cref="IllegalArgumentException"> if <code>value</code> is of an
///     *             unsupported type (including <code>null</code>) </exception>
///     
		void SetProperty(string key, object value);

///    
///     <summary> * Removes the property associated with the given key and returns the old
///     * value. If there's no property associated with the key, <code>null</code>
///     * will be returned.
///     *  </summary>
///     * <param name="key"> the property key </param>
///     * <returns> the property value that used to be associated with the given key </returns>
///     
		object RemoveProperty(string key);

///    
///     <summary> * Returns all existing property keys, or an empty iterable if this property
///     * container has no properties.
///     *  </summary>
///     * <returns> all property keys on this property container </returns>
///     
	// TODO: figure out concurrency semantics
		IEnumerable<string> GetPropertyKeys();

///    
///     <summary> * Returns all currently valid property values, or an empty iterable if this
///     * node has no properties. All values are of a supported property type, i.e.
///     * a Java primitive, a <seealso cref="String String"/> or an array of any of the
///     * supported types.
///     * <p>
///     * <b>Note:</b> This method is deprecated and <i>will</i> be removed in
///     * future releases. Use a combination of <seealso cref="getPropertyKeys()"/> and
///     * <seealso cref="getProperty(String)"/> to achieve the same result.
///     *  </summary>
///     * <returns> all property values </returns>
///     * @deprecated in favor of using <seealso cref="getPropertyKeys()"/> in combination
///     *             with <seealso cref="getProperty(String)"/>. 
///     
	// TODO: figure out concurrency semantics
		[Obsolete("in favor of using <seealso cref=getPropertyKeys()/> in combination")]
		IEnumerable<object> GetPropertyValues();
	}
}